package org.streets.workflow.engine.task;

import java.util.List;

import org.streets.workflow.engine.ITaskInstance;
import org.streets.workflow.engine.IWorkItem;
import org.streets.workflow.engine.WorkflowEngine;
import org.streets.workflow.engine.WorkflowException;
import org.streets.workflow.engine.internal.WorkflowEngineImpl;
import org.streets.workflow.engine.persistence.IWorkflowDAO;
import org.streets.workflow.model.WFFormTask;
import org.streets.workflow.model.WFTask;
import org.streets.workflow.model.resource.WFParticipant;

/**
 *
 */
public class DefaultFormTaskHandler implements ITaskHandler {

    /* (non-Javadoc)
     * @see org.fireflow.engine.taskinstance.ITaskInstanceRunner#run(org.fireflow.engine.IWorkflowSession, org.fireflow.engine.RuntimeContext, org.fireflow.engine.IProcessInstance, org.fireflow.engine.ITaskInstance)
     */
    public void handle(WorkflowEngine engine, ITaskInstance task) throws WorkflowException {
        if (!WFTask.FORM.equals(task.getTaskType())){
            throw new WorkflowException(task.getProcess(), task.getActivityModel(),
                    "DefaultFormTaskInstanceRunner：TaskInstance的任务类型错误，只能为FORM类型");
        }

        DefaultDynamicTaskAssignor dynamicAssignmentHandler = ((WorkflowEngineImpl)engine).consumeCurrentDynamicTaskHandler();
        WFFormTask taskModel = (WFFormTask)task.getTaskModel();

        WFParticipant performer = taskModel.getPerformer();//获取到form的执行者
        if (performer == null || performer.getAssignmentHandler().trim().equals("")) {
            throw new WorkflowException(task.getProcess(),
                    task.getActivityModel(),
                    "流程定义错误，Form类型的 task必须指定performer及其AssignmentHandler");
        }
        assign(engine, task, taskModel, performer, dynamicAssignmentHandler);
    }

    /**
     * 分配， 按照当前任务的参与者插入工单
     * @param currentSession
     * @param processInstance
     * @param runtimeContext
     * @param task
     * @param formTaskModel
     * @param partModel
     * @param dynamicTaskHandler
     * @throws WorkflowException
     * @throws KernelException
     */
    protected void assign(WorkflowEngine engine, ITaskInstance task, WFFormTask formTaskModel, WFParticipant partModel, DefaultDynamicTaskAssignor dynamicTaskHandler) throws WorkflowException {
        //如果有指定的Actor，则按照指定的Actor分配任务
        if (dynamicTaskHandler != null) {
            dynamicTaskHandler.assign(engine, task, partModel.getName());
        } else {
        	IWorkflowDAO persistenceService = engine.getRuntimeContext().getPersistenceService();
        	//从数据库中查询任务信息
        	List<ITaskInstance> taskInstanceList = persistenceService.findTasks(task.getProcess().getId(), task.getActivityModelId());
        	ITaskInstance theLastCompletedTaskInstance = null;

        	for (int i=0;taskInstanceList!=null && i<taskInstanceList.size();i++){
        		ITaskInstance tmp = taskInstanceList.get(i);
        		if (tmp.getId().equals(task.getId()))continue;
                if (!tmp.getTaskModelId().equals(task.getTaskModelId()))continue;
                if (tmp.getState().intValue()!=ITaskInstance.COMPLETED)continue;
        		if ( theLastCompletedTaskInstance==null){
        			theLastCompletedTaskInstance = tmp;
        		}else{
        			if (theLastCompletedTaskInstance.getStepNum().intValue()<tmp.getStepNum().intValue()){
        				theLastCompletedTaskInstance=tmp;
        			}
        		}
        	}

        	//如果是循环且LoopStrategy==REDO，则分配个上次完成该工作的操作员
            if (theLastCompletedTaskInstance!=null && (WFFormTask.REDO.equals(formTaskModel.getLoopStrategy()) || engine.isInWithdrawOrRejectOperation())) {
            	List<IWorkItem> workItemList = persistenceService.findWorkItems(theLastCompletedTaskInstance.getId());
            	
                for (int k = 0; k < workItemList.size(); k++) {
                    IWorkItem completedWorkItem = workItemList.get(k);
                    IWorkItem newFromWorkItem = engine.createWorkItem(task, completedWorkItem.getActorId());
                    engine.claimWorkItem(newFromWorkItem); //并自动签收
                }
            } else {
            	ITaskAssignor assignor = null;
            	//FIXME dzb 得到注入的assignmentHandler
            	//TODO ... IOC
            	try {
                    assignor = (ITaskAssignor)Class.forName(partModel.getAssignmentHandler()).newInstance();
                } catch (Exception e) {
                   
                }            	
                //modified by wangmj 20090904
                assignor.assign(engine, task, partModel.getName());
            }
        }


    }
}
